package top.vanchor.flexible.controller.admin;


import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.metadata.IPage;
import top.vanchor.flexible.common.Res;
import top.vanchor.flexible.config.initexception.ErrorEnum;
import top.vanchor.flexible.entity.BackAuthGroup;
import top.vanchor.flexible.service.IBackAdminService;
import top.vanchor.flexible.service.IBackAuthGroupRuleService;
import top.vanchor.flexible.service.IBackAuthGroupService;
import top.vanchor.flexible.service.IBackAuthRuleService;
import top.vanchor.flexible.utils.JWTUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.*;


import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 前端控制器
 * </p>
 *
 * @author Ding
 * @since 2022-01-27
 */
@Api("后台角色控制器")
@RestController
@RequestMapping("/admin/adminGroup")
public class BackAuthGroupController {

    @Resource
    private IBackAuthGroupService service;
    @Resource
    private IBackAdminService adminService;
    @Resource
    private IBackAuthGroupRuleService groupRuleService;
    @Resource
    private IBackAuthRuleService ruleService;

    private static final String SUPER_ADMIN = "SUPER_ADMIN";

    /**
     * 获取角色列表（无分页）
     *
     * @return res
     */
    @ApiOperation("获取角色")
    @ResponseBody
    @GetMapping("/getRoles")
    public Res<JSONObject> getRoles() {
        JSONObject jsonTemp = new JSONObject();
        List<BackAuthGroup> groups = service.getRoles();
        jsonTemp.put("list", groups);
        return Res.success(jsonTemp);
    }

    /**
     * 获取角色列表（分页）
     *
     * @param pageNo   页码
     * @param pageSize 每页数
     * @param title    名称
     * @return res
     */
    @ApiOperation("获取角色列表")
    @ResponseBody
    @GetMapping("/getList")
    public Res<IPage<BackAuthGroup>> getList(
            @RequestParam("pageNo") Integer pageNo,
            @RequestParam("pageSize") Integer pageSize,
            @RequestParam(name = "title", defaultValue = "") String title) {
        Integer aId = JWTUtils.getAuthorId();
        Integer groupId = adminService.getById(aId).getAGroupId();
        //根据角色id获取角色权限
        BackAuthGroup group = service.getById(groupId);
        if (SUPER_ADMIN.equals(group.getRole())) {
            //最高权限，必然获取
            return Res.success(service.getList(pageNo, pageSize, title));
        } else {
            //普通权限，必然不能拥有系统管理的权限-防止篡位
            return Res.error(ErrorEnum.HIGHEST_AUTH);
        }
    }

    /**
     * 添加、修改角色
     *
     * @param bean BackAuthGroup实体
     * @return res
     */
    @ApiOperation("添加、修改角色")
    @PostMapping("/doEdit")
    @ResponseBody
    public Res<JSONObject> doEdit(@RequestBody BackAuthGroup bean) {
        int editNum = 0;
        /*
          添加要求
          各角色标题唯一
         */
        if (bean.getGroupId() == null) {
            //超级管理员必须唯一，超级管理员不可以拥有增删改查的操作
            if (SUPER_ADMIN.equals(bean.getRole())) {
                //不能添加超级管理员角色
                return Res.error(ErrorEnum.ROLE_UNCHANGEABLE);
            }
            if (service.getByTitle(bean.getTitle()) > 0) {
                //存在该名称的角色
                return Res.error(ErrorEnum.ROLE_CONFLICT);
            }
        }
            /*
              编辑要求
              各角色标题唯一
             */
        if (bean.getGroupId() != null) {
            //超级管理员不可以拥有增删改查的操作
            BackAuthGroup beforeEditBean = service.getGroupById(bean.getGroupId());
            if (SUPER_ADMIN.equals(beforeEditBean.getRole())) {
                //不能编辑超级管理员角色
                return Res.error(ErrorEnum.ROLE_UNCHANGEABLE);
            }
            if (service.getByTitle(bean.getTitle()) > 0 && !beforeEditBean.getTitle().equals(bean.getTitle())) {
                //存在该名称的角色
                return Res.error(ErrorEnum.ROLE_CONFLICT);
            }
        }
            /*
              没有被拦截
              走添加/编辑方法
             */
        boolean isAdd = bean.getGroupId() == null;
        editNum += service.doEdit(bean);
        if (editNum > 0) {
            return Res.success(isAdd ? "添加成功" : "编辑成功");
        } else {
            return Res.error();
        }
    }

    /**
     * 删除角色
     *
     * @param data {ids:（字符串逗号隔开）-需要处理成数组和list}
     * @return res
     */
    @ApiOperation("删除角色")
    @ResponseBody
    @PostMapping("/doDelete")
    public Res<JSONObject> doDelete(@RequestBody Map<String,List<Integer>> data) {
        //处理前端数据
        List<Integer> ids = data.get("ids");
        //遍历，确认其身份不是SUPER_ADMIN，否则return
        int beforeIdsSize = ids.size();
        for (int i = 0; i < ids.size(); i++) {
            if (SUPER_ADMIN.equals(service.getGroupById(ids.get(i)).getRole())) {
                ids.remove(i--);
            }
        }
        if (ids.size() < beforeIdsSize) {
            return Res.error("选择中含有" + (beforeIdsSize - ids.size()) + "个超级管理角色，请取消相应的勾选");
        }
        //初始化
        int delNum = 0;
        //执行删除角色
        delNum += service.doDeleteBy(ids);
        //删除赋予该角色的管理员
        adminService.deleteUserByGroupIds(ids);
        if (delNum >= ids.size()) {
            return Res.success("已删除" + delNum + "个角色");
        } else if (delNum > 0) {
            return Res.success("部分删除成功，" + delNum + "/" + ids.size());
        } else {
            //删除失败
            return Res.error();
        }
    }

    /**
     * 禁用 or 启用 角色
     *
     * @param bean BackAuthGroup实体
     * @return res
     */
    @ApiOperation("禁用/启用管理员")
    @PostMapping("/changeStatus")
    @ResponseBody
    public Res<JSONObject> changeStatus(@RequestBody BackAuthGroup bean) {
        JSONObject jsonObject = new JSONObject();
        if (service.doEdit(bean) > 0) {
            return Res.success(bean.getStatus() == 1 ? "启用成功！" : "禁用成功！");
        } else {
            return Res.error();
        }
    }

    /**
     * 根据角色id获取权限ids
     *
     * @param data {id:角色id}
     * @return res
     */
    @ApiOperation("根据角色id获取权限ids")
    @PostMapping("/getRuleIdsById")
    @ResponseBody
    public Res<JSONObject> getRuleIdsById(@RequestBody JSONObject data) {
        JSONObject jsonTemp = new JSONObject();
        Integer groupId = Integer.parseInt(String.valueOf(data.get("id")));
        List<Integer> ruleIds = new ArrayList<>();
        ruleIds = groupRuleService.getRuleIdsByGroupId(groupId);
        jsonTemp.put("list", ruleIds);
        return Res.success(jsonTemp);
    }

    /**
     * 为角色分配权限
     *
     * @param data {id:角色id,ruleIds:权限ids}
     * @return res
     */
    @ApiOperation("为角色分配权限")
    @PostMapping("/doRulesEdit")
    @ResponseBody
    public Res<JSONObject> doRulesEdit(@RequestBody JSONObject data) {
        Integer groupId = Integer.parseInt(String.valueOf(data.get("id")));
        if (SUPER_ADMIN.equals(service.getById(groupId).getRole())) {
            //不能编辑超级管理员的权限
            return Res.error(ErrorEnum.ROLE_UNCHANGEABLE);
        }
        //获取要分配的所有权限id
        List<Integer> ruleIds = (List<Integer>) data.get("rules");
        //若选择菜单里存在最高权限菜单（不应该分配给普通管理员）
        if (ruleIds.size() != 0 && ruleService.checkIsForbidden(ruleIds)) {
            //这里面存在不被允许选择的id
            return Res.error(ErrorEnum.RULE_ASSIGN_NO_PERMISSION);
        }
        //正常添加
        groupRuleService.doRulesEdit(groupId, ruleIds);
        return Res.success("分配成功");
    }
}
